﻿using System;
using System.Diagnostics;
using System.Text.RegularExpressions;
using JetBrains.Annotations;
using WikiDoc.Utils;

namespace WikiDoc.Lines
{
    /// <summary>
    /// 表示一个经过解析后的 Wiki 文本行的信息
    /// </summary>
    public class WikiLine
    {
        /// <summary>
        /// 初始化 <see cref="WikiLine"/> 类的新实例。
        /// </summary>
        /// <param name="line">The line.</param>
        public WikiLine([NotNull] string line) : this(line, LineTypes.Normal)
        {
        }

        /// <summary>
        /// 初始化 <see cref="WikiLine"/> 类的新实例。
        /// </summary>
        /// <param name="line">The line.</param>
        /// <param name="type">The type.</param>
        protected WikiLine([NotNull] string line, LineTypes type)
        {
            if (line == null) throw new ArgumentNullException("line");

            Type = type;
            Line = line;
        }

        /// <summary>
        /// 行的类型
        /// </summary>
        public LineTypes Type { get; protected set; }

        /// <summary>
        /// Gets the line.
        /// </summary>
        /// <value>The line.</value>
        [NotNull]
        public string Line { get; protected set; }

        /// <summary>
        /// 
        /// </summary>
        [NotNull] 
        public static readonly WikiLine EofLine = new WikiLine(string.Empty, LineTypes.Eof);

        /// <summary>
        /// 
        /// </summary>
        [NotNull] 
        public static readonly WikiLine EmptyLine = new WikiLine(String.Empty, LineTypes.Empty);

        /// <summary>
        /// Gets the line info.
        /// </summary>
        /// <param name="line">The line.</param>
        /// <returns></returns>
        [NotNull]
        public static WikiLine Parse([NotNull] string line)
        {
            if (line == null) throw new ArgumentNullException("line");

            if (line.Length == 0)
            {
                return EmptyLine;
            }

            if (char.IsWhiteSpace(line[0]))
            {
                var ret = BulletListLine.TryParse(line)
                       ?? NumberListLine.TryParse(line)
                       ?? AlphaListLine.TryParse(line)
                       ?? DefineListLine.TryParse(line)
                       ?? TryEmptyLine(line)
                       ?? IndentLine.TryParse(line);

                Debug.Assert(ret != null);

                return ret;
            }

            return CommentLine.TryParse(line)
                   ?? HeaderLine.TryParse(line)
                   ?? HorizonLine.TryParse(line)
                   ?? TableLine.TryParse(line)
                   ?? CustomSectionLine.TryParse(line)
                   ?? new WikiLine(line);
        }

        private static WikiLine TryEmptyLine(string line)
        {
            return line.IsBlank() ? EmptyLine : null;
        }
    }

}
